/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.pdx.cs.guavadata.query;

import edu.pdx.cs.guavadata.Channel;
import edu.pdx.cs.guavadata.Transform;
import edu.pdx.cs.guavadata.condition.Condition;
import edu.pdx.cs.guavadata.domain.Domain;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 *
 * @author VuTran
 */
public class Filter extends Operator {

    // Filter is like a relational select operator.  Has 'or' semantics between conditions - to do 'and', just add another Filter operator
    
    Operator child;
    List<String> columnAliases;
    List<Condition> columnConditions;

    public Operator getChild() {
        return child;
    }

    public void setChild(Operator child) {
        this.child = child;
    }

    public List<String> getColumnAliases() {
        return columnAliases;
    }

    public void setColumnAliases(List<String> columnAliases) {
        this.columnAliases = columnAliases;
    }

    public List<Condition> getColumnConditions() {
        return columnConditions;
    }

    public void setColumnConditions(List<Condition> columnConditions) {
        this.columnConditions = columnConditions;
    }

    public Filter(Operator child) {
        this.child = child;
        child.parent = this;
        this.columnAliases = new ArrayList<String>();
        this.columnConditions = new ArrayList<Condition>();

        this.exposedColumns = new ArrayList<String>(this.child.exposedColumns);
        this.exposedDomains = new ArrayList<Domain>(this.child.exposedDomains);
    }

    public Filter(Operator child, Collection<String> columnAliases, Collection<Condition> conditions) {
        this.child = child;
        child.parent = this;
        this.columnAliases = new ArrayList<String>(columnAliases);
        this.columnConditions = new ArrayList<Condition>(conditions);

        this.exposedColumns = new ArrayList<String>(this.child.exposedColumns);
        this.exposedDomains = new ArrayList<Domain>(this.child.exposedDomains);
    }

    @Override
    public SqlText visit(Provider qv) {
        return qv.transform(this);
    }

    @Override
    public void visit(Channel c, String table) {
        c.mapAliases(this, table);
    }

    @Override
    public void visit(Transform t, Command c) {
        t.expand(this, c);
    }

    @Override
    public void notifyChange(Operator old, Operator newOp) {
        if (this.child == old) {
            this.child = newOp;
            newOp.parent = this;
        }
    }

    @Override
    public Operator clone() {
        return new Filter(child, columnAliases, columnConditions);
    }

    public void addCondition(String column, Condition condition) {
        this.columnAliases.add(column);
        this.columnConditions.add(condition);
    }

    public String getConditionString() {
        if (columnAliases.size() <= 0)
            return "";
        String o = columnAliases.get(0) + columnConditions.get(0).toString();

        for (int i = 1; i < columnAliases.size(); i++) {
            o = o + " OR " + columnAliases.get(i) + columnConditions.get(i).toString();
        }
        return o;
    }
}
